package org.jiuling.basics.util;


import org.jiuling.basics.exception.BasicsException;
import org.jiuling.basics.validation.AnnotationVerify;
import org.jiuling.basics.validation.ArrayVerify;
import org.jiuling.basics.validation.ObjectVerify;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;



/**
 * 注解扩展功能
 * @author 紫灵
 * @date 2023年02月15日 22时32分06秒
 */
public class AnnotationUtil {

    /** 私有化构造方法，禁止创建对象 */
    private AnnotationUtil() {}

    /**
     * 获取注解值
     * @param annotations 注解数组
     * @param annotationClass 注解类
     * @param valueName 值名称
     * @return 值
     */
    public static Object getAnnotationValue(Annotation[] annotations,Class<?> annotationClass, String valueName) throws BasicsException {
        Object annotation = getAnnotation(annotations, annotationClass);
        if(!ObjectVerify.isNull(annotation)){
            return getAnnotationValue((Annotation) annotation,valueName);
        }
        return null;
    }

    /**
     * 获取注解值
     * @param annotation 注解
     * @param valueName 值名称
     * @return 值
     */
    public static Object getAnnotationValue(Annotation annotation,String valueName) throws BasicsException {
        InvocationHandler invocationHandler = Proxy.getInvocationHandler(annotation);
        Map<String,Object> map = (Map<String, Object>) ClassUtil.getFieldValue(invocationHandler, "memberValues");
        if(!map.isEmpty()){
            return map.get(valueName);
        }
        return null;
    }

    /**
     * 获取指定注解
     * @param annotations 注解数组
     * @param annotationClass 指定注解
     * @return 注解
     */
    public static Object getAnnotation(Annotation[] annotations,Class<?> annotationClass){
        // 便利注解数组
        for (Annotation annotation : annotations) {
            // 判断是否为元注解
            if(!AnnotationVerify.isMetaAnnotation(annotation)){
                if(annotation.annotationType().equals(annotationClass)){
                    return annotation;
                }
                // 获取子注解
                Annotation[] subAnnotations = annotation.annotationType().getAnnotations();
                // 判断子注解列表是否为空
                if(!ArrayVerify.isEmpty(subAnnotations)){
                    // 获取子注解中指定注解
                    Object subAnnotation = getAnnotation(subAnnotations, annotationClass);
                    if(!ObjectVerify.isNull(subAnnotation)){
                        return subAnnotation;
                    }
                }
            }
        }
        return null;
    }
}
